﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace CommonLib.Util;

public static class StrUtil
{

    public const int INDEX_NOT_FOUND = -1;

    public static string Space(this string str, int num)
    {
        if (num <= 0) return str;
        return $"{new string(' ', num * 4)}{str}";
    }

    public static bool IsFull(this string str)
    {
        if (string.IsNullOrEmpty(str)) return true;
        return (str.Count(s => s.Equals('(')) == str.Count(s => s.Equals(')')))
             && (str.Count(s => s.Equals('[')) == str.Count(s => s.Equals(']')));
    }

    public static string ReplaceSpace(this string str)
    {
        if (string.IsNullOrEmpty(str)) return str;
        str = str.Replace("\t", " ");
        return Regex.Replace(str, "\\s{2,}", " ").Trim();
    }

    public static string RealSql(this string str)
    {
        if (string.IsNullOrEmpty(str)) return str;
        return Regex.Replace(str, "(--.*)|(/\\*.*?\\*/)", "").Trim();
    }

    public static string RealStr(this string str)
    {
        if (string.IsNullOrEmpty(str)) return str;
        return Regex.Replace(str, "(//.*)|(\\{[^\\$].*?\\})|(\\(\\*.*?\\*\\))", "").Trim();
    }

    public static string CommentStr(this string str)
    {
        var sub = new List<string>();
        if (string.IsNullOrEmpty(str)) return "";
        var mats = Regex.Matches(str, "(//.*)|(\\{[^\\$](.*?)\\})|(\\(\\*(.*?)\\*\\))");
        if (mats.Count > 0)
        {
            foreach (Match mat in mats)
            {
                sub.Add(mat.Value);
            }
            var line = string.Join(" ", sub);
            if (!Regex.IsMatch(line, "[ぁ-んァ-ン]")) return "";
            return line.StartsWith("//") ? line : $"//{line}";
        }
        else return "";
    }

    public static bool EqualsIgnoreCase(this string str, string val)
    {
        if (string.IsNullOrEmpty(str) || string.IsNullOrEmpty(val)) return false;
        return str.ToLower().Equals(val.ToLower());
    }

    public static bool StartsWithIngoreCase(this string str, string val)
    {
        if (string.IsNullOrEmpty(str) || string.IsNullOrEmpty(val)) return false;
        return str.ToLower().StartsWith(val.ToLower());
    }



    public static int IndexOfIgnoreCase(this string str, string searchStr, int start = 0)
    {
        if (string.IsNullOrEmpty(str) || string.IsNullOrEmpty(searchStr))
        {
            return INDEX_NOT_FOUND;
        }
        if (start < 0)
        {
            return INDEX_NOT_FOUND;
        }
        int endLimit = str.Length - searchStr.Length + 1;
        if (start > endLimit || str.Length <= start)
        {
            return INDEX_NOT_FOUND;
        }
        if (searchStr.Length == 0)
        {
            return start;
        }
        var res = str.Substring(start).ToLower();
        return res.IndexOf(searchStr.ToLower());
    }

    public static string ReplaceFirst(this string value, string oldValue, string newValue)
    {
        if (string.IsNullOrEmpty(oldValue))
            return value;

        int idx = value.IndexOfIgnoreCase(oldValue);
        if (idx == -1)
            return value;
        value = value.Remove(idx, oldValue.Length);
        return value.Insert(idx, newValue);
    }

    public static string FullWord(this string str, string word)
    {
        var res = str[..str.IndexOf(word)].Trim();
        while (!res.IsFull())
        {
            var temp = str.Replace(res, "").Trim();
            if (temp.Contains(word))
            {
                res = $"{res} {temp[..temp.IndexOf(word)].Trim()}";
            }
            else res = $"{res} {temp}";
        }
        return res;
    }

    public static string[] TrimSplit(this string str, char chr) 
    {
        return str.Split(chr,StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
    }

    public static string[] TrimSplit(this string str, string chr)
    {
        return str.Split(chr, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
    }
}
